package com.ruoyi.work.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.enums.DelFlagEnum;
import com.ruoyi.common.enums.FlowMenuEnum;
import com.ruoyi.common.enums.ProcessStatus;
import com.ruoyi.common.exception.DataException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.flowable.api.domain.WfBusinessProcess;
import com.ruoyi.flowable.api.domain.WorkSign;
import com.ruoyi.flowable.api.domain.WorkSignFile;
import com.ruoyi.flowable.api.domain.bo.WfTaskBo;
import com.ruoyi.flowable.api.domain.vo.WorkSignVo;
import com.ruoyi.flowable.api.service.IWfBusinessProcessServiceApi;
import com.ruoyi.flowable.api.service.IWfProcessServiceApi;
import com.ruoyi.flowable.api.service.IWfTaskServiceApi;
import com.ruoyi.work.mapper.WorkSignMapper;
import com.ruoyi.work.service.IWorkSignFileService;
import com.ruoyi.work.service.IWorkSignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;

/**
 * 签署Service业务层处理
 *
 * @author fengcheng
 * @date 2025-03-18
 */
@Service
public class WorkSignServiceImpl implements IWorkSignService {
    @Autowired
    private WorkSignMapper workSignMapper;

    @Autowired
    private IWorkSignFileService workSignFileService;

    @Autowired
    private IWfBusinessProcessServiceApi wfBusinessProcessServiceApi;

    @Autowired
    private IWfProcessServiceApi processServiceApi;

    @Autowired
    private IWfTaskServiceApi flowTaskServiceApi;

    /**
     * 查询签署
     *
     * @param signId 签署主键
     * @return 签署
     */
    @Override
    public WorkSignVo selectWorkSignBySignId(Long signId) {
        WorkSignVo workSignVo = workSignMapper.selectWorkSignBySignId(signId);
        WorkSignFile workSignFile = new WorkSignFile();
        workSignFile.setSignId(signId);
        workSignVo.setSignFileList(workSignFileService.selectWorkSignFileList(workSignFile));
        return workSignVo;
    }

    /**
     * 查询签署列表
     *
     * @param workSignVo 签署
     * @return 签署
     */
    @Override
    public List<WorkSign> selectWorkSignList(WorkSignVo workSignVo) {
        return workSignMapper.selectWorkSignList(workSignVo);
    }

    /**
     * 新增签署
     *
     * @param workSignVo 签署
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertWorkSign(WorkSignVo workSignVo) {
        workSignVo.setCreateTime(DateUtils.getNowDate());
        int i = workSignMapper.insertWorkSign(workSignVo);
        insertWorkSignFile(workSignVo);

        workSignVo.setBusinessId(String.valueOf(workSignVo.getSignId()));
        workSignVo.setBusinessProcessType(FlowMenuEnum.SIGN_FLOW_MENU.getCode());

        if (ProcessStatus.RUNNING.getStatus().equals(workSignVo.getSchedule())) {
            WorkSignVo workSign = new WorkSignVo();
            workSignVo.setSignFileList(null);
            String processInstanceId = processServiceApi.startProcessByDefId(workSignVo.getDefinitionId(), BeanUtil.beanToMap(workSignVo, new HashMap<>(16), false, false));
            WfBusinessProcess wfBusinessProcess = new WfBusinessProcess();
            wfBusinessProcess.setProcessId(processInstanceId);
            wfBusinessProcess.setBusinessId(String.valueOf(workSignVo.getSignId()));
            wfBusinessProcess.setBusinessProcessType(FlowMenuEnum.SIGN_FLOW_MENU.getCode());
            wfBusinessProcessServiceApi.insertWfBusinessProcess(wfBusinessProcess);


            workSign.setProcessId(processInstanceId);
            workSign.setSchedule(ProcessStatus.RUNNING.getStatus());
            workSign.setSignId(workSignVo.getSignId());
            return workSignMapper.updateWorkSign(workSign);
        }
        return i;
    }

    /**
     * 新增签署文件
     *
     * @param workSignVo
     */
    private void insertWorkSignFile(WorkSignVo workSignVo) {
        List<WorkSignFile> signFileList = workSignVo.getSignFileList();
        if (ObjectUtil.isNull(signFileList) || signFileList.size() == 0) {
            return;
        }
        for (WorkSignFile signFile : signFileList) {
            signFile.setSignId(workSignVo.getSignId());
        }
        workSignFileService.insertWorkSignFileList(signFileList);
    }

    /**
     * 修改签署
     *
     * @param workSignVo 签署
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateWorkSign(WorkSignVo workSignVo) {
        workSignVo.setUpdateTime(DateUtils.getNowDate());
        workSignFileService.deleteWorkSignFileBySignId(workSignVo.getSignId());
        insertWorkSignFile(workSignVo);

        if (ProcessStatus.RUNNING.getStatus().equals(workSignVo.getSchedule())) {
            workSignVo.setBusinessId(String.valueOf(workSignVo.getSignId()));
            workSignVo.setBusinessProcessType(FlowMenuEnum.SIGN_FLOW_MENU.getCode());
            workSignVo.setSignFileList(null);
            String processInstanceId = processServiceApi.startProcessByDefId(workSignVo.getDefinitionId(), BeanUtil.beanToMap(workSignVo, new HashMap<>(16), false, false));
            WfBusinessProcess wfBusinessProcess = new WfBusinessProcess();
            wfBusinessProcess.setProcessId(processInstanceId);
            wfBusinessProcess.setBusinessId(String.valueOf(workSignVo.getSignId()));
            wfBusinessProcess.setBusinessProcessType(FlowMenuEnum.SIGN_FLOW_MENU.getCode());
            wfBusinessProcessServiceApi.insertWfBusinessProcess(wfBusinessProcess);
            workSignVo.setProcessId(processInstanceId);
            workSignVo.setSchedule(ProcessStatus.RUNNING.getStatus());
        }
        return workSignMapper.updateWorkSign(workSignVo);
    }

    /**
     * 批量删除签署
     *
     * @param signIds 需要删除的签署主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteWorkSignBySignIds(Long[] signIds) {
        for (Long signId : signIds) {
            WorkSignVo workSignVo = checkExistence(signId);
            if (ProcessStatus.UNAPPROVED.getStatus().equals(workSignVo.getSchedule()) || ProcessStatus.CANCELED.getStatus().equals(workSignVo.getSchedule())) {
                wfBusinessProcessServiceApi.deleteWfBusinessProcessByBusinessId(String.valueOf(signId), FlowMenuEnum.SIGN_FLOW_MENU.getCode());
//                WfTaskBo wfTaskBo = new WfTaskBo();
//                wfTaskBo.setProcInsId(workRiskVo.getProcessId());
//                flowTaskServiceApi.stopProcess(wfTaskBo);
                processServiceApi.deleteProcessByIds(new String[]{workSignVo.getProcessId()});
            }
        }
        return workSignMapper.deleteWorkSignBySignIds(signIds);
    }

    /**
     * 校验签章
     *
     * @param riskId
     * @return
     */
    private WorkSignVo checkExistence(Long riskId) {
        WorkSignVo workSignVo = selectWorkSignBySignId(riskId);
        if (DelFlagEnum.DELETE.getCode().equals(workSignVo.getDelFlag())) {
            throw new DataException("该[[" + workSignVo.getUserName() + "]]签章已被删除");
        }
        return workSignVo;
    }

    /**
     * 删除签署信息
     *
     * @param signId 签署主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteWorkSignBySignId(Long signId) {
        int i = workSignMapper.deleteWorkSignBySignId(signId);
        WorkSignVo workSignVo = checkExistence(signId);
        if (ProcessStatus.UNAPPROVED.getStatus().equals(workSignVo.getSchedule()) || ProcessStatus.CANCELED.getStatus().equals(workSignVo.getSchedule())) {
            wfBusinessProcessServiceApi.deleteWfBusinessProcessByBusinessId(String.valueOf(signId), FlowMenuEnum.SIGN_FLOW_MENU.getCode());
//                WfTaskBo wfTaskBo = new WfTaskBo();
//                wfTaskBo.setProcInsId(workRiskVo.getProcessId());
//                flowTaskServiceApi.stopProcess(wfTaskBo);
            processServiceApi.deleteProcessByIds(new String[]{workSignVo.getProcessId()});
        }
        return i;
    }

    /**
     * 重新申请
     *
     * @param signId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int reapply(Long signId) {
        WorkSignVo workSignVo = checkExistence(signId);
        processServiceApi.deleteProcessByIds(new String[]{workSignVo.getProcessId()});
        return submit(signId);
    }

    /**
     * 撤销审核
     *
     * @param signId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int revoke(Long signId) {
        wfBusinessProcessServiceApi.deleteWfBusinessProcessByBusinessId(String.valueOf(signId), FlowMenuEnum.SIGN_FLOW_MENU.getCode());
        WorkSignVo workSignVo = checkExistence(signId);
        WorkSignVo workSign = new WorkSignVo();


        WfTaskBo wfTaskBo = new WfTaskBo();
        wfTaskBo.setProcInsId(workSignVo.getProcessId());
        flowTaskServiceApi.stopProcess(wfTaskBo);
        processServiceApi.deleteProcessByIds(new String[]{workSignVo.getProcessId()});

        workSign.setProcessId("");
        workSign.setSignId(signId);
        workSign.setSchedule(ProcessStatus.UNAPPROVED.getStatus());
        return workSignMapper.updateWorkSign(workSign);
    }

    /**
     * 提交审核
     *
     * @param signId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int submit(Long signId) {
        WorkSignVo workSignVo = checkExistence(signId);

        WorkSignVo workSign = new WorkSignVo();

        // 启动流程
        workSignVo.setBusinessId(String.valueOf(signId));
        workSignVo.setBusinessProcessType(FlowMenuEnum.SIGN_FLOW_MENU.getCode());
        String processInstanceId = processServiceApi.startProcessByDefId(workSignVo.getDefinitionId(), BeanUtil.beanToMap(workSignVo, new HashMap<>(16), false, false));
        WfBusinessProcess wfBusinessProcess = new WfBusinessProcess();
        wfBusinessProcess.setProcessId(processInstanceId);
        wfBusinessProcess.setBusinessId(String.valueOf(signId));
        wfBusinessProcess.setBusinessProcessType(FlowMenuEnum.SIGN_FLOW_MENU.getCode());
        wfBusinessProcessServiceApi.insertWfBusinessProcess(wfBusinessProcess);

        workSign.setProcessId(processInstanceId);
        workSign.setSignId(signId);
        workSign.setSchedule(ProcessStatus.RUNNING.getStatus());
        return workSignMapper.updateWorkSign(workSign);
    }

    /**
     * 查询签署文件列表
     *
     * @param signId
     * @return
     */
    @Override
    public List<WorkSignFile> listSignFile(Long signId) {
        WorkSignFile workSignFile = new WorkSignFile();
        workSignFile.setSignId(signId);
        return workSignFileService.selectWorkSignFileList(workSignFile);
    }
}
